/*
 * Copyright (c) 2010 Sylvestre Gallon <syl@pmbsd.org>
 *
 * Permission to use, copy, modify, and distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 */

#include <sys/types.h>
#include <sys/queue.h>
#include <objc.h>
#include <class.h>
#include <dispatch.h>


#define __CLS_INFO(cls) ((cls)->info)
#define __CLS_ISINFO(cls, m) ((__CLS_INFO(cls)&m)==m)
#define __CLS_SETINFO(cls, m) (__CLS_INFO(cls) |= m)

#define _CLS_META 0x2L
#define _CLS_CLASS 0x1L

#define CLS_ISMETA(cls) ((cls)&&__CLS_ISINFO(cls, _CLS_META))
#define CLS_ISCLASS(cls) ((cls)&&__CLS_ISINFO(cls, _CLS_CLASS))

/* XXX */
IMP
objc_msg_lookup_super(Super super, SEL op)
{
	if (super->self) {
		return (__objc_get_from_dispatch(objc_get_class((char *)super->cl), op));
	} else {
		return (IMP)nil_method;
	}
}

IMP
objc_msg_lookup(id receiver, SEL op)
{
        IMP res = 0;
	Class cl;

        if (receiver) {
		cl = receiver->cl;

		if (CLS_ISMETA(cl))
			cl = (Class) receiver;

                res = __objc_get_from_dispatch(cl, op);
                if (res == 0) {
                        __objc_install_dispatch_table_for_class(cl);
                        res = __objc_get_from_dispatch(cl, op);
                }
        }

        if (res == 0)
                return (IMP)nil_method;
        return res;
}
